package com.xsystem.api;

import java.util.Map;

import com.xsystem.api.exception.RequiredParamsMissingException;
import com.xsystem.api.util.MessagesUtil;
import com.xsystem.orm.user.User;
import com.xsystem.user.UserEngine;
import com.xsystem.user.exception.UserNotFoundException;
import com.xsystem.user.exception.UserUnauthorizedException;

// Classes that extends this abstract class will have execute() method
// with the user authenticated as the 2nd parameter.
// If authentication fails, Api.execute() will return the error message
// and the subclass will not be called.
//
// Note, subclasses must state the parent="authenticateApi" in the XML. 

public abstract class AuthenticatedApi extends Api {

	public static final String ERROR_ACCOUNT_NOT_FOUND = "accountNotFound";
	public static final String ERROR_USER_UNAUTHORIZED = "userUnauthorized";
	public static final String ERROR_USER_SUSPENDED = "userSuspended";
	public static final String ERROR_USER_EXPIRED = "userExpired";
	public static final String ERROR_EMPTY_LOGIN = "emptyLogin";

	protected UserEngine userEngine;

	public UserEngine getUserEngine() {
		return userEngine;
	}

	public void setUserEngine(UserEngine userEngine) {
		this.userEngine = userEngine;
	}

	public abstract Map<String, Object> execute(Map<String, String> parameters,
			User user) throws RequiredParamsMissingException;

	@Override
	public Map<String, Object> executeApi(Map<String, String> parameters)
			throws RequiredParamsMissingException {
		try {
			User user = this.getUser(parameters);
			logUser(user);
			return execute(parameters, user);
		} catch (UserNotFoundException ex) {
			return prepareCustomErrorResponse(ERROR_ACCOUNT_NOT_FOUND,
					MessagesUtil.getProperty(AuthenticatedApi.class,
							ERROR_ACCOUNT_NOT_FOUND, null));
		} catch (UserUnauthorizedException ex) {
			return prepareCustomErrorResponse(ERROR_USER_UNAUTHORIZED,
					MessagesUtil.getProperty(AuthenticatedApi.class,
							ERROR_USER_UNAUTHORIZED, null));
		}
	}

	private User getUser(Map<String, String> parameters)
			throws UserNotFoundException, UserUnauthorizedException {

		String username = parameters.get(Api.IN_USERNAME);
		String password = parameters.get(Api.IN_PASSWORD);

		if (username == null) {
			throw new UserNotFoundException();
		}

		if (password == null) {
			throw new UserUnauthorizedException();
		}

		return userEngine.getAuthenticatedUser(username, password);
	}
}
